<template>
	<div class="hw-picker-container" v-if="visible">
		<!-- 遮罩层：对齐日期选择器配置 -->
		<div class="hw-picker__mask" @click="handleCancel" :style="{ backgroundColor: maskColor }"></div>

		<!-- 选择器主体：统一尺寸/圆角配置 -->
		<div class="hw-picker__wrapper" :style="{
			width: wrapperWidth,
			borderRadius: borderRadius,
			backgroundColor: wrapperBgColor
		}">
			<!-- 操作栏：完全对齐日期选择器（取消+标题+确认） -->
			<div class="hw-picker__header" :style="{ borderBottomColor: headerBorderColor }">
				<span class="hw-picker__btn hw-picker__btn--cancel" @click="handleCancel"
					:style="{ color: cancelTextColor, fontSize: btnFontSize }"
					:class="{ 'hw-picker__btn--disabled': disabled }">
					{{ cancelText }}
				</span>
				<h3 class="hw-picker__title"
					:style="{ color: titleColor, fontSize: titleFontSize, fontWeight: titleFontWeight }">
					{{ title }}
				</h3>
				<span class="hw-picker__btn hw-picker__btn--confirm" @click="handleConfirm"
					:style="{ color: confirmTextColor, fontSize: btnFontSize }"
					:class="{ 'hw-picker__btn--disabled': disabled || !isValidValue }">
					{{ confirmText }}
				</span>
			</div>

			<!-- 内容区：刻度尺选择（核心功能保留） -->
			<div class="hw-picker__body">
				<!-- 身高选择 -->
				<div class="hw-picker__section">
					<div class="hw-picker__ruler-container" ref="heightRulerRef"
						@click="(e) => handleRulerClick(e, 'height')">
						<!-- 中间指示线 -->
						<div class="hw-picker__indicator-line"></div>
						<!-- 刻度尺滚动层 -->
						<div class="hw-picker__ruler-wrapper"
							:style="{ transform: `translateX(${heightTranslateX}px)` }"
							@touchstart="(e) => handleDragStart(e, 'height')"
							@touchmove="(e) => handleDragMove(e, 'height')" @touchend="handleDragEnd"
							@mousedown="(e) => handleDragStart(e, 'height')"
							@mousemove="(e) => handleDragMove(e, 'height')" @mouseup="handleDragEnd"
							@mouseleave="handleDragEnd">
							<div v-for="mark in heightMarks" :key="`height-${mark}`" class="hw-picker__ruler-mark"
								:class="[
									{ 'hw-picker__ruler-mark--major': mark % 10 === 0 },
									{ 'hw-picker__ruler-mark--current': mark === currentHeight }
								]" :style="{ left: `${calculateMarkLeft(mark, 'height')}px` }">
								<span class="hw-picker__mark-text" v-if="mark % 10 === 0">
									{{ mark }}{{ heightUnit }}
								</span>
							</div>
						</div>
					</div>
				</div>

				<!-- 体重选择 -->
				<div class="hw-picker__section">
					<div class="hw-picker__ruler-container" ref="weightRulerRef"
						@click="(e) => handleRulerClick(e, 'weight')">
						<!-- 中间指示线 -->
						<div class="hw-picker__indicator-line"></div>
						<!-- 刻度尺滚动层 -->
						<div class="hw-picker__ruler-wrapper"
							:style="{ transform: `translateX(${weightTranslateX}px)` }"
							@touchstart="(e) => handleDragStart(e, 'weight')"
							@touchmove="(e) => handleDragMove(e, 'weight')" @touchend="handleDragEnd"
							@mousedown="(e) => handleDragStart(e, 'weight')"
							@mousemove="(e) => handleDragMove(e, 'weight')" @mouseup="handleDragEnd"
							@mouseleave="handleDragEnd">
							<div v-for="mark in weightMarks" :key="`weight-${mark}`" class="hw-picker__ruler-mark"
								:class="[
									{ 'hw-picker__ruler-mark--major': mark % 10 === 0 },
									{ 'hw-picker__ruler-mark--current': mark === currentWeight }
								]" :style="{ left: `${calculateMarkLeft(mark, 'weight')}px` }">
								<span class="hw-picker__mark-text" v-if="mark % 10 === 0">
									{{ mark }}{{ weightUnit }}
								</span>
							</div>
						</div>
					</div>
				</div>
			</div>
		</div>
	</div>
</template>

<script setup lang="ts">
import { ref, computed, watch, onBeforeUnmount, nextTick } from 'vue'

// ------------------------------ 1. 类型定义（对齐日期选择器风格） ------------------------------
/** 选择器类型（身高/体重） */
type PickerType = 'height' | 'weight'

/** 组件Props类型（与日期选择器保持API一致） */
interface HwPickerProps {
	visible: boolean
	disabled?: boolean
	title?: string
	cancelText?: string
	confirmText?: string
	// 业务参数（身高/体重）
	initialHeight?: number
	initialWeight?: number
	minHeight?: number
	maxHeight?: number
	minWeight?: number
	maxWeight?: number
	heightUnit?: string
	weightUnit?: string
	// 样式自定义（完全对齐日期选择器）
	maskColor?: string
	wrapperWidth?: string
	wrapperBgColor?: string
	borderRadius?: string
	headerBorderColor?: string
	titleColor?: string
	titleFontSize?: string
	titleFontWeight?: string
	cancelTextColor?: string
	confirmTextColor?: string
	btnFontSize?: string
	// 刻度尺样式
	rulerHeight?: string
	indicatorLineColor?: string
	markColor?: string
	majorMarkColor?: string
	currentMarkColor?: string
	markFontSize?: string
}

/** 组件Emits类型 */
interface HwPickerEmits {
	(e: 'confirm', value: { height: number; weight: number; heightUnit: string; weightUnit: string }): void
	(e: 'cancel'): void
	(e: 'heightChange', value: number): void
	(e: 'weightChange', value: number): void
}

// ------------------------------ 2. Props与默认值（对齐日期选择器） ------------------------------
const props = withDefaults(defineProps<HwPickerProps>(), {
	disabled: false,
	title: '选择身高体重',
	cancelText: '取消',
	confirmText: '确认',
	// 业务默认值
	initialHeight: 170,
	initialWeight: 60,
	minHeight: 50,
	maxHeight: 250,
	minWeight: 10,
	maxWeight: 200,
	heightUnit: 'CM',
	weightUnit: 'KG',
	// 样式默认值（与日期选择器完全一致）
	maskColor: 'rgba(0, 0, 0, 0.5)',
	wrapperWidth: '90%',
	wrapperBgColor: '#fff',
	borderRadius: '16px',
	headerBorderColor: '#eee',
	titleColor: '#333',
	titleFontSize: '18px',
	titleFontWeight: '600',
	cancelTextColor: '#00897B',
	confirmTextColor: '#00897B',
	btnFontSize: '16px',
	// 刻度尺样式默认值
	rulerHeight: '120px',
	indicatorLineColor: '#00897B',
	markColor: '#ccc',
	majorMarkColor: '#999',
	currentMarkColor: '#00897B',
	markFontSize: '14px'
})

// 事件定义
const emit = defineEmits<HwPickerEmits>()

// ------------------------------ 3. 响应式数据（精简对齐） ------------------------------
// 选中值
const currentHeight = ref(props.initialHeight)
const currentWeight = ref(props.initialWeight)
// 刻度尺位置
const heightTranslateX = ref(0)
const weightTranslateX = ref(0)
// 拖动状态
const dragState = ref<{
	isDragging: boolean
	type: PickerType | null
	startX: number
	startTranslateX: number
}>({ isDragging: false, type: null, startX: 0, startTranslateX: 0 })
// 容器尺寸
const containerWidth = ref(0)
// 参考元素
const heightRulerRef = ref<HTMLElement | null>(null)
const weightRulerRef = ref<HTMLElement | null>(null)
// 防抖计时器（对齐日期选择器）
const debounceTimer = ref<NodeJS.Timeout | null>(null)

// ------------------------------ 4. 计算属性（逻辑复用） ------------------------------
/** 身高刻度列表 */
const heightMarks = computed<number[]>(() => {
	return Array.from({ length: props.maxHeight - props.minHeight + 1 }, (_, i) => props.minHeight + i)
})

/** 体重刻度列表 */
const weightMarks = computed<number[]>(() => {
	return Array.from({ length: props.maxWeight - props.minWeight + 1 }, (_, i) => props.minWeight + i)
})

/** 刻度宽度（固定5px，与日期选择器逻辑一致） */
const markWidth = computed<number>(() => 5)

/** 选中值是否有效 */
const isValidValue = computed<boolean>(() => {
	return currentHeight.value >= props.minHeight && currentHeight.value <= props.maxHeight &&
		currentWeight.value >= props.minWeight && currentWeight.value <= props.maxWeight
})

// ------------------------------ 5. 核心方法（对齐日期选择器初始化逻辑） ------------------------------
/** 初始化容器宽度 */
const initContainerWidth = () => {
	const container = heightRulerRef.value || weightRulerRef.value
	if (!container) return
	containerWidth.value = container.getBoundingClientRect().width
}

/** 计算刻度尺滚动位置（使目标值居中） */
const calculateTranslateX = (targetValue: number, type: PickerType): number => {
	if (containerWidth.value === 0) return 0
	const minVal = props[`min${type.charAt(0).toUpperCase() + type.slice(1)}`] as number
	return -(targetValue - minVal) * markWidth.value + containerWidth.value / 2 - markWidth.value / 2
}

/** 更新刻度尺位置（防抖处理，对齐日期选择器） */
const updateRulerPosition = (type: PickerType, targetValue: number) => {
	if (debounceTimer.value) clearTimeout(debounceTimer.value)
	debounceTimer.value = setTimeout(() => {
		const translateX = calculateTranslateX(targetValue, type)
		if (type === 'height') heightTranslateX.value = translateX
		else weightTranslateX.value = translateX
	}, 30)
}

/** 初始化组件数据（对齐日期选择器initData） */
const initData = () => {
	// 初始化容器宽度
	initContainerWidth()
	// 初始化刻度尺位置
	updateRulerPosition('height', props.initialHeight)
	updateRulerPosition('weight', props.initialWeight)
	// 同步初始值
	currentHeight.value = props.initialHeight
	currentWeight.value = props.initialWeight
}

/** 计算单个刻度的left位置 */
const calculateMarkLeft = (mark: number, type: PickerType): number => {
	const minVal = props[`min${type.charAt(0).toUpperCase() + type.slice(1)}`] as number
	return (mark - minVal) * markWidth.value
}

// ------------------------------ 6. 拖动与点击处理（保留核心功能） ------------------------------
/** 拖动开始 */
const handleDragStart = (e: TouchEvent | MouseEvent, type: PickerType) => {
	if (props.disabled) return
	const clientX = 'touches' in e ? e.touches[0].clientX : e.clientX
	const startTranslateX = type === 'height' ? heightTranslateX.value : weightTranslateX.value

	dragState.value = { isDragging: true, type, startX: clientX, startTranslateX }
	e.preventDefault?.()
}

/** 拖动中 */
const handleDragMove = (e: TouchEvent | MouseEvent) => {
	if (props.disabled || !dragState.value.isDragging || !dragState.value.type) return

	const { type, startX, startTranslateX } = dragState.value
	const clientX = 'touches' in e ? e.touches[0].clientX : e.clientX
	const moveX = clientX - startX

	// 计算新位置
	let newTranslateX = startTranslateX + moveX
	const maxTranslateX = containerWidth.value / 2
	const rulerTotalWidth = (props[`max${type.charAt(0).toUpperCase() + type.slice(1)}`] as number -
		props[`min${type.charAt(0).toUpperCase() + type.slice(1)}`] as number) * markWidth.value
	const minTranslateX = containerWidth.value / 2 - rulerTotalWidth
	newTranslateX = Math.max(minTranslateX, Math.min(maxTranslateX, newTranslateX))

	// 计算当前值
	const minVal = props[`min${type.charAt(0).toUpperCase() + type.slice(1)}`] as number
	const currentVal = Math.round(minVal + (containerWidth.value / 2 - newTranslateX) / markWidth.value)
	const validVal = Math.max(minVal, Math.min(props[`max${type.charAt(0).toUpperCase() + type.slice(1)}`] as number, currentVal))

	// 更新状态
	if (type === 'height') {
		heightTranslateX.value = newTranslateX
		if (validVal !== currentHeight.value) {
			currentHeight.value = validVal
			emit('heightChange', validVal)
		}
	} else {
		weightTranslateX.value = newTranslateX
		if (validVal !== currentWeight.value) {
			currentWeight.value = validVal
			emit('weightChange', validVal)
		}
	}
}

/** 拖动结束 */
const handleDragEnd = () => {
	dragState.value = { isDragging: false, type: null, startX: 0, startTranslateX: 0 }
}

/** 刻度尺点击（快速定位） */
const handleRulerClick = (e: TouchEvent | MouseEvent, type: PickerType) => {
	if (props.disabled) return
	const container = type === 'height' ? heightRulerRef.value : weightRulerRef.value
	if (!container || containerWidth.value === 0) return

	const clientX = 'touches' in e ? e.touches[0].clientX : e.clientX
	const relativeX = clientX - container.getBoundingClientRect().left
	const minVal = props[`min${type.charAt(0).toUpperCase() + type.slice(1)}`] as number
	const targetVal = Math.round(minVal + (relativeX - containerWidth.value / 2) / markWidth.value)
	const validVal = Math.max(minVal, Math.min(props[`max${type.charAt(0).toUpperCase() + type.slice(1)}`] as number, targetVal))

	// 更新值与位置
	if (type === 'height') {
		currentHeight.value = validVal
		updateRulerPosition('height', validVal)
		emit('heightChange', validVal)
	} else {
		currentWeight.value = validVal
		updateRulerPosition('weight', validVal)
		emit('weightChange', validVal)
	}
}

// ------------------------------ 7. 操作栏事件（与日期选择器完全一致） ------------------------------
/** 取消选择 */
const handleCancel = () => {
	if (props.disabled) return
	emit('cancel')
}

/** 确认选择 */
const handleConfirm = () => {
	if (props.disabled || !isValidValue.value) return
	emit('confirm', {
		height: currentHeight.value,
		weight: currentWeight.value,
		heightUnit: props.heightUnit,
		weightUnit: props.weightUnit
	})
}

// ------------------------------ 8. 生命周期与监听（对齐日期选择器） ------------------------------
// 监听visible变化：显示时初始化
watch(() => props.visible, (isVisible) => {
	if (isVisible) {
		nextTick(initData) // 确保DOM渲染后初始化
	}
}, { immediate: true })

// 监听初始值变化：实时同步
watch([() => props.initialHeight, () => props.initialWeight], ([newHeight, newWeight]) => {
	if (props.visible) {
		currentHeight.value = newHeight
		currentWeight.value = newWeight
		updateRulerPosition('height', newHeight)
		updateRulerPosition('weight', newWeight)
	}
})

// 组件销毁前清除计时器
onBeforeUnmount(() => {
	if (debounceTimer.value) clearTimeout(debounceTimer.value)
})
</script>
<style scoped lang="scss">
// ------------------------------ SCSS变量（完全对齐日期选择器命名风格） ------------------------------
$prefix: hw-picker; // 前缀与日期选择器区分（date-picker → hw-picker）
$animation-duration: 0.3s; // 与日期选择器一致的动画时长
$header-padding: 16px; // 标题栏内边距对齐
$ruler-height: 120px; // 刻度尺高度（可通过Props自定义）
$indicator-line-width: 4px; // 指示线宽度
$indicator-line-height: 50px; // 指示线高度

// ------------------------------ 基础样式（结构对齐日期选择器） ------------------------------
.#{$prefix}-container {
	position: fixed;
	top: 0;
	left: 0;
	width: 100vw;
	height: 100vh;
	z-index: 999;
	display: flex;
	justify-content: center;
	align-items: center;
	padding: 20px;
	box-sizing: border-box;
}

// 遮罩层（与日期选择器一致）
.#{$prefix}__mask {
	position: absolute;
	top: 0;
	left: 0;
	width: 100%;
	height: 100%;
	transition: background-color $animation-duration;
}

// 选择器主体（动画、尺寸对齐）
.#{$prefix}__wrapper {
	overflow: hidden;
	max-width: 400px; // 与日期选择器一致的最大宽度
	position: relative;
	z-index: 1000;
	animation: fadeIn $animation-duration ease-out; // 相同的淡入动画
}

// 淡入动画（完全复用日期选择器）
@keyframes fadeIn {
	from {
		opacity: 0;
		transform: scale(0.95);
	}

	to {
		opacity: 1;
		transform: scale(1);
	}
}

// 操作栏（结构、样式对齐）
.#{$prefix}__header {
	display: flex;
	justify-content: space-between;
	align-items: center;
	padding: $header-padding;
	border-bottom: 1px solid;
	transition: border-bottom-color $animation-duration;

	// 按钮通用样式
	.#{$prefix}__btn {
		cursor: pointer;
		transition: color $animation-duration, opacity $animation-duration;

		&--disabled {
			opacity: 0.6;
			pointer-events: none;
		}
	}

	// 取消按钮（左对齐）
	.#{$prefix}__btn--cancel {
		margin-right: auto;
	}

	// 确认按钮（右对齐）
	.#{$prefix}__btn--confirm {
		margin-left: auto;
	}

	// 标题（居中）
	.#{$prefix}__title {
		font-size: inherit;
		font-weight: inherit;
		color: inherit;
		transition: color $animation-duration, font-size $animation-duration;
	}
}

// 内容区（刻度尺容器）
.#{$prefix}__body {
	padding: 20px $header-padding;
}

// 单个选择区块（身高/体重）
.#{$prefix}__section {
	margin-bottom: 30px;
	position: relative;
}

// 刻度尺容器
.#{$prefix}__ruler-container {
	position: relative;
	height: $ruler-height;
	width: 100%;
	overflow: hidden;
	cursor: pointer;
}

// 中间指示线（可通过Props自定义颜色）
.#{$prefix}__indicator-line {
	position: absolute;
	left: 50%;
	top: 50%;
	transform: translate(-50%, -50%);
	width: $indicator-line-width;
	height: $indicator-line-height;
	border-radius: calc($indicator-line-width / 2);
	background-color: v-bind(indicatorLineColor); // 绑定Props颜色
	z-index: 20;
}

// 刻度尺滚动层
.#{$prefix}__ruler-wrapper {
	position: absolute;
	top: 0;
	left: 0;
	height: 100%;
	white-space: nowrap;
	transition: transform 0.08s ease;
}

// 刻度标记
.#{$prefix}__ruler-mark {
	position: absolute;
	width: 2px;
	height: 30px;
	background-color: v-bind(markColor); // 绑定Props颜色
	bottom: 20px;
	transition: background-color $animation-duration;

	// 主刻度（每10个）
	&--major {
		height: 40px;
		background-color: v-bind(majorMarkColor); // 绑定Props颜色
	}

	// 当前选中刻度
	&--current {
		background-color: v-bind(currentMarkColor); // 绑定Props颜色
	}

	// 刻度文本
	.#{$prefix}__mark-text {
		position: absolute;
		bottom: 50px;
		left: 50%;
		transform: translateX(-50%);
		font-size: v-bind(markFontSize); // 绑定Props字体大小
		color: #666;
		white-space: nowrap;
	}
}
</style>